// -------------------------------------------------------------------------
//    @FileName         :    NFAsynNosql.h
//    @Author           :    GaoYi
//    @Date             :    2017-09-27
//    @Module           :   NFAsynNosql
//
// -------------------------------------------------------------------------

#include "NFAsynNosqlTest.h"
#include "NFComm/NFMessageDefine/NFProtocolDefine.hpp"

bool NFCAsynNosqlTest::Init()
{
    m_pAsyNosqlModule = pPluginManager->FindModule<NFIAsyNoSqlModule>();
    m_pNosqlModule = pPluginManager->FindModule<NFINoSqlModule>();
    m_pKernelModule = pPluginManager->FindModule<NFIKernelModule>();
    m_pCommonRedisModule = pPluginManager->FindModule<NFICommonDBModule>();
    m_pAsyMysqlModule = pPluginManager->FindModule<NFIAsyMysqlModule>();
    m_pClassModule = pPluginManager->FindModule<NFIClassModule>();
    return true;
}

bool NFCAsynNosqlTest::AfterInit()
{
    return true;
}

bool NFCAsynNosqlTest::Execute()
{
    static bool run = false;
    if (run)
    {
        return true;
    }

    run = true;
    //SetBuildData();
    //m_pAsyNosqlModule->Del(NFGUID(), "gaoyi", this, &NFCAsynNosqlTest::DelGaoyi);
    //m_pAsyNosqlModule->Exists(NFGUID(), "gaoyi", this, &NFCAsynNosqlTest::ExistsGaoyi);
    //m_pAsyNosqlModule->Expire(NFGUID(), "gaoyi", 100, this, &NFCAsynNosqlTest::ExpireGaoyi);
    //m_pAsyNosqlModule->Set(NFGUID(), "gaoyi", "shabi", this, &NFCAsynNosqlTest::SetGaoyi);
    //m_pAsyNosqlModule->Get(NFGUID(), "gaoyi", this, &NFCAsynNosqlTest::GetGaoyi);
    //m_pAsyNosqlModule->SetNX(NFGUID(), "gaoyi", "shabi", this, &NFCAsynNosqlTest::SetNXGaoyi);
    //m_pAsyNosqlModule->SetEX(NFGUID(), "gaoyi", "shabi", 100, this, &NFCAsynNosqlTest::SetEXGaoyi);
    //m_pAsyNosqlModule->HSet(NFGUID(), "gaoyi", "shabi", "erzi", this, &NFCAsynNosqlTest::HSetGaoyi);
    //m_pAsyNosqlModule->HGet(NFGUID(), "gaoyi", "shabi", this, &NFCAsynNosqlTest::HGetGaoyi);
    //m_pAsyNosqlModule->ZAdd(NFGUID(), "rank_money", 100, "gaoyi", this, &NFCAsynNosqlTest::GetGaoyi);
    //m_pAsyNosqlModule->ZAdd(NFGUID(), "rank_money", 200, "gaoyi1", this, &NFCAsynNosqlTest::GetGaoyi);
    //m_pAsyNosqlModule->ZAdd(NFGUID(), "rank_money", 300, "gaoyi2", this, &NFCAsynNosqlTest::GetGaoyi);
    //m_pAsyNosqlModule->ZAdd(NFGUID(), "rank_money", 300, "gaoyi3", this, &NFCAsynNosqlTest::GetGaoyi);
    //m_pAsyNosqlModule->ZIncrBy(NFGUID(), "rank_money", "gaoyi3", 100, this, &NFCAsynNosqlTest::GetGaoyi);
    //m_pAsyNosqlModule->ZScore(NFGUID(), "rank_money", "gaoyi3", this, &NFCAsynNosqlTest::GetGaoyi);
    //m_pAsyNosqlModule->ZCard(NFGUID(), "rank_money", this, &NFCAsynNosqlTest::GetGaoyi);
    //m_pAsyNosqlModule->ZRank(NFGUID(), "rank_money", "gaoyi3", this, &NFCAsynNosqlTest::GetGaoyi);
    //m_pAsyNosqlModule->ZCount(NFGUID(), "rank_money", 0, 200, this, &NFCAsynNosqlTest::GetGaoyi);
    //m_pAsyNosqlModule->ZRevRange(NFGUID(), "rank_money", 0, 100, this, &NFCAsynNosqlTest::GetGaoyi);
    //m_pAsyNosqlModule->ZRevRank(NFGUID(), "rank_money", "gaoyi", this, &NFCAsynNosqlTest::GetGaoyi);
    //m_pAsyNosqlModule->ZRange(NFGUID(), "rank_money", 0, 100, this, &NFCAsynNosqlTest::GetGaoyi);
    //m_pAsyNosqlModule->ZRangeByScore(NFGUID(), "rank_money", 300,400, this, &NFCAsynNosqlTest::GetGaoyi);

    //m_pAsyNosqlModule->HDel(NFGUID(), "gaoyi", "shabi", this, &NFCAsynNosqlTest::HDelGaoyi);
    //m_pAsyNosqlModule->HExists(NFGUID(), "gaoyi", "shabi", this, &NFCAsynNosqlTest::HExistsGaoyi);

    //BuildObjectDataSaveToMysql();
    //BuildObjectDataLoadFromMysql();
    return true;
}

void NFCAsynNosqlTest::DelGaoyi(const NFGUID& self, NFMsg::PackNoSqlParam& nosqlParam, const std::string& strUseData)
{
    if (nosqlParam.ret() != 0)
    {
        std::cout << "Nosql Bad!" << std::endl;
        return;
    }

    if (nosqlParam.opt_ret())
    {
        std::cout << "Del Key: " << nosqlParam.str_key() << " Success" << std::endl;
    }
    else
    {
        std::cout << "Del Failed" << std::endl;
    }
}

void NFCAsynNosqlTest::ExistsGaoyi(const NFGUID& self, NFMsg::PackNoSqlParam& nosqlParam, const std::string& strUseData)
{
    if (nosqlParam.ret() != 0)
    {
        std::cout << "Nosql Bad!" << std::endl;
        return;
    }

    if (nosqlParam.opt_ret())
    {
        std::cout << "Exists Key: " << nosqlParam.str_key() << " Success" << std::endl;
    }
    else
    {
        std::cout << "Exists Failed" << std::endl;
    }
}

void NFCAsynNosqlTest::ExpireGaoyi(const NFGUID& self, NFMsg::PackNoSqlParam& nosqlParam, const std::string& strUseData)
{
    if (nosqlParam.ret() != 0)
    {
        std::cout << "Nosql Bad!" << std::endl;
        return;
    }

    if (nosqlParam.opt_ret())
    {
        std::cout << "Expire Key: " << nosqlParam.str_key() << " Success" << std::endl;
    }
    else
    {
        std::cout << "Expire Failed" << std::endl;
    }
}

void NFCAsynNosqlTest::ExpireatGaoyi(const NFGUID& self, NFMsg::PackNoSqlParam& nosqlParam, const std::string& strUseData)
{
    if (nosqlParam.ret() != 0)
    {
        std::cout << "Nosql Bad!" << std::endl;
        return;
    }

    if (nosqlParam.opt_ret())
    {
        std::cout << "Expireat Key: " << nosqlParam.str_key() << " Success" << std::endl;
    }
    else
    {
        std::cout << "Expireat Failed" << std::endl;
    }
}

void NFCAsynNosqlTest::SetNXGaoyi(const NFGUID& self, NFMsg::PackNoSqlParam& nosqlParam, const std::string& strUseData)
{
    if (nosqlParam.ret() != 0)
    {
        std::cout << "Nosql Bad!" << std::endl;
        return;
    }

    if (nosqlParam.opt_ret())
    {
        std::cout << "SetNX Key:" << nosqlParam.str_key() << " Value:" << nosqlParam.str_value() << " Success" << std::endl;
    }
    else
    {
        std::cout << "SetNX Failed" << std::endl;
    }
}

void NFCAsynNosqlTest::SetEXGaoyi(const NFGUID& self, NFMsg::PackNoSqlParam& nosqlParam, const std::string& strUseData)
{
    if (nosqlParam.ret() != 0)
    {
        std::cout << "Nosql Bad!" << std::endl;
        return;
    }

    if (nosqlParam.opt_ret())
    {
        std::cout << "SetEX Key:" << nosqlParam.str_key() << " Value:" << nosqlParam.str_value() << " Success" << std::endl;
    }
    else
    {
        std::cout << "SetEX Failed" << std::endl;
    }
}

void NFCAsynNosqlTest::SetGaoyi(const NFGUID& self, NFMsg::PackNoSqlParam& nosqlParam, const std::string& strUseData)
{
    if (nosqlParam.ret() != 0)
    {
        std::cout << "Nosql Bad!" << std::endl;
        return;
    }

    if (nosqlParam.opt_ret())
    {
        std::cout << "Set Key:" << nosqlParam.str_key() << " Value:" << nosqlParam.str_value() << " Success" << std::endl;
    }
    else
    {
        std::cout << "Set Failed" << std::endl;
    }
}

void NFCAsynNosqlTest::GetGaoyi(const NFGUID& self, NFMsg::PackNoSqlParam& nosqlParam, const std::string& strUseData)
{
    std::cout << nosqlParam.DebugString() << std::endl;
    if (nosqlParam.ret() != 0)
    {
        std::cout << "Nosql Bad!" << std::endl;
        return;
    }

    if (nosqlParam.opt_ret())
    {
        std::cout << "Get Key:" << nosqlParam.str_key() << " Value:" << nosqlParam.str_value() << " Success" << std::endl;
    }
    else
    {
        std::cout << "Get Failed" << std::endl;
    }
}

void NFCAsynNosqlTest::HSetGaoyi(const NFGUID& self, NFMsg::PackNoSqlParam& nosqlParam, const std::string& strUseData)
{
    if (nosqlParam.ret() != 0)
    {
        std::cout << "Nosql Bad!" << std::endl;
        return;
    }

    if (nosqlParam.opt_ret())
    {
        std::cout << "HSet Key:" << nosqlParam.str_key() << " Field" << nosqlParam.str_field() << " Value:" << nosqlParam.str_value() << " Success" << std::endl;
    }
    else
    {
        std::cout << "HSet Failed" << std::endl;
    }
}

void NFCAsynNosqlTest::HDelGaoyi(const NFGUID& self, NFMsg::PackNoSqlParam& nosqlParam, const std::string& strUseData)
{
    if (nosqlParam.ret() != 0)
    {
        std::cout << "Nosql Bad!" << std::endl;
        return;
    }

    if (nosqlParam.opt_ret())
    {
        std::cout << "HDel Key:" << nosqlParam.str_key() << " Field:" << nosqlParam.str_field() << " Success" << std::endl;
    }
    else
    {
        std::cout << "HDel Failed" << std::endl;
    }
}

void NFCAsynNosqlTest::HExistsGaoyi(const NFGUID& self, NFMsg::PackNoSqlParam& nosqlParam, const std::string& strUseData)
{
    if (nosqlParam.ret() != 0)
    {
        std::cout << "Nosql Bad!" << std::endl;
        return;
    }

    if (nosqlParam.opt_ret())
    {
        std::cout << "HExists Key:" << nosqlParam.str_key() << " Field:" << nosqlParam.str_field() << " Success" << std::endl;
    }
    else
    {
        std::cout << "HExists Failed" << std::endl;
    }
}

void NFCAsynNosqlTest::HGetGaoyi(const NFGUID& self, NFMsg::PackNoSqlParam& nosqlParam, const std::string& strUseData)
{
    if (nosqlParam.ret() != 0)
    {
        std::cout << "Nosql Bad!" << std::endl;
        return;
    }

    if (nosqlParam.opt_ret())
    {
        std::cout << "HGet Key:" << nosqlParam.str_key() << " Field:" << nosqlParam.str_field() << " Value:" << nosqlParam.str_value() << " Success" << std::endl;
    }
    else
    {
        std::cout << "HGet Failed" << std::endl;
    }
}

bool NFCAsynNosqlTest::BeforeShut()
{
    return true;
}

bool NFCAsynNosqlTest::Shut()
{
    return true;
}

void NFCAsynNosqlTest::SetBuildData()
{
    BEGIN_PROFILE("Sync Set");
    for (int i = 0; i < setCount; i++)
    {
        NF_SHARE_PTR<NFINoSqlDriver> xNoSqlDriver = m_pNosqlModule->GetDriverBySuitConsistent();
        if (xNoSqlDriver)
        {
            std::string strKey = "gaoyi" + lexical_cast<std::string>(setCount);
            xNoSqlDriver->Set(strKey, strKey);
        }
    }
    END_PROFILE();

    startTime = NFGetTime();
    BEGIN_PROFILE("ASync Set");
    for (int i = 0; i < setCount; i++)
    {
        std::string strKey = "gaoyi" + lexical_cast<std::string>(setCount);
        m_pAsyNosqlModule->Set(NFGUID(), strKey, strKey, this, &NFCAsynNosqlTest::SetBuildDataRetFun);
    }
    END_PROFILE();
}

void NFCAsynNosqlTest::SetBuildDataRetFun(const NFGUID& self, NFMsg::PackNoSqlParam& nosqlParam, const std::string& strUseData)
{
    setCountRet++;
    if (nosqlParam.ret() != 0)
    {
        std::cout << "Nosql Bad!" << std::endl;
        return;
    }

    if (nosqlParam.opt_ret())
    {
        setCountRetSuc++;
    }
    else
    {
        setCountRetFail++;
    }

    if (setCountRet >= setCount)
    {
        endTime = NFGetTime();
        std::cout << "asyn nosql use time:" << endTime - startTime << std::endl;
        std::cout << "asyn nosql handle finish" << std::endl;
    }
}

void NFCAsynNosqlTest::BuildObjectDataLoadFromMysql()
{
    static bool run = false;
    static int count = 0;
    if (run)
    {
        return;
    }

    if (count == 0)
    {
        startTime = NFGetTime();
    }

    BEGIN_PROFILE("Load Object");

    for (int i = 0; i < 100; i++)
    {
        count++;

        std::string strUseData;
        std::vector<std::string> fieldVec;
        NF_SHARE_PTR<NFIPropertyManager> pStaticClassPropertyManager = m_pClassModule->GetClassPropertyManager(NFrame::Player::ThisName());
        m_pCommonRedisModule->ConvertPropertyManagerToPB(pStaticClassPropertyManager, fieldVec);
        const MYSQL_RETURN_VECKEY_VECVALUE_FUNCTOR mFunReturnVeckKeyValueRsp = std::bind(&NFCAsynNosqlTest::LoadOfflineDataReturnFunc, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5);
        m_pAsyMysqlModule->Query(NFrame::Player::ThisName(), count, 1, fieldVec, mFunReturnVeckKeyValueRsp, strUseData);
    }

    END_PROFILE();

    if (count >= setCount)
    {
        run = true;
    }
}

void NFCAsynNosqlTest::LoadOfflineDataReturnFunc(const NFGUID& self, const int nRet, const std::vector<std::string>& fieldVec, const std::vector<std::string>& valueVec, const std::string& strUseData)
{
    setCountRet ++;
    if (nRet != 0)
    {
        std::cout << "Mysql Bad!" << std::endl;
        return;
    }

    if (nRet == 0 && fieldVec.size() > 0 && valueVec.size() > 0 && valueVec.size() % fieldVec.size() == 0)
    {
        setCountRetSuc ++;
    }
    else
    {
        setCountRetFail ++;
    }

    if (setCountRet >= setCount)
    {
        endTime = NFGetTime();
        std::cout << "asyn load object use time:" << endTime - startTime
                  << " all:" << setCount << " suc:" << setCountRetSuc << " fail:" << setCountRetFail << std::endl;
        std::cout << "asyn load object handle finish" << std::endl;
    }
}

void NFCAsynNosqlTest::BuildObjectDataSaveToMysql()
{
    static bool run = false;
    static int count = 0;
    if (run)
    {
        return;
    }

    if (count == 0)
    {
        startTime = NFGetTime();
    }

    BEGIN_PROFILE("Create And Save Object");
    for (int i = 0; i < 100; i++)
    {
        count++;

        NF_SHARE_PTR<NFIObject> pObject;
        BEGIN_PROFILE("Create Object");
        pObject = m_pKernelModule->CreateObject(NFGUID(), NFrame::Player::ThisName(), "0", NFDataList());
        END_PROFILE();

        BEGIN_PROFILE("Save Object");
        NFGUID self = pObject->Self();
        std::vector<std::string> vecField;
        std::vector<std::string> vecValue;
        m_pCommonRedisModule->SaveStroragePropertyInfo(self, pObject->GetPropertyManager(), vecField, vecValue);
        std::string strUseData;
        m_pAsyMysqlModule->Updata(self, NFrame::Player::ThisName(), self.ToString(), vecField, vecValue, this, &NFCAsynNosqlTest::BuildObjectDataSaveToMysqlRet, strUseData);
        END_PROFILE();
    }
    END_PROFILE();

    if (count >= setCount)
    {
        run = true;
    }
}

void NFCAsynNosqlTest::BuildObjectDataSaveToMysqlRet(const NFGUID& self, const int ret, const std::string& strUseData)
{
    setCountRet++;
    if (ret != 0)
    {
        std::cout << "Mysql Bad!" << std::endl;
        return;
    }

    if (ret == 0)
    {
        setCountRetSuc++;
    }
    else
    {
        setCountRetFail++;
    }

    if (setCountRet >= setCount)
    {
        endTime = NFGetTime();
        std::cout << "asyn save object use time:" << endTime - startTime
                  << " all:" << setCount << " suc:" << setCountRetSuc << " fail:" << setCountRetFail << std::endl;
        std::cout << "asyn save object handle finish" << std::endl;
    }
}


void NFCAsynNosqlTest::BuildObjectDataSaveToRedis()
{
    static bool run = false;
    static int count = 0;
    if (run)
    {
        return;
    }

    if (count == 0)
    {
        startTime = NFGetTime();
    }

    BEGIN_PROFILE("Create And Save Object");
    for (int i = 0; i < 100; i++)
    {
        count++;

        NF_SHARE_PTR<NFIObject> pObject;
        BEGIN_PROFILE("Create Object");
        pObject = m_pKernelModule->CreateObject(NFGUID(), NFrame::Player::ThisName(), "0", NFDataList());
        END_PROFILE();

        BEGIN_PROFILE("Save Object");
        NFGUID self = pObject->Self();
        NFMsg::PackNoSqlParam xMsg;
        xMsg.set_self(pObject->Self().ToString());
        xMsg.set_cache_property_key(m_pCommonRedisModule->GetPropertyCacheKey(self));
        xMsg.set_cache_record_key(m_pCommonRedisModule->GetRecordCacheKey(self));
        xMsg.set_storage_property_key(m_pCommonRedisModule->GetPropertyStorageKey(self));
        xMsg.set_storage_record_key(m_pCommonRedisModule->GetRecordStorageKey(self));

        m_pCommonRedisModule->SaveCachePropertyInfo(self, pObject->GetPropertyManager(), *xMsg.mutable_cache_property_value());
        m_pCommonRedisModule->SaveCacheRecordInfo(self, pObject->GetRecordManager(), *xMsg.mutable_cache_record_value());
        m_pCommonRedisModule->SaveStroragePropertyInfo(self, pObject->GetPropertyManager(), *xMsg.mutable_storage_property_value());
        m_pCommonRedisModule->SaveStrorageRecordInfo(self, pObject->GetRecordManager(), *xMsg.mutable_storage_record_value());

        m_pAsyNosqlModule->SaveNFObject(self, xMsg, this, &NFCAsynNosqlTest::BuildObjectDataSaveToRedisRet);
        END_PROFILE();
    }
    END_PROFILE();

    if (count >= setCount)
    {
        run = true;
    }
}

void NFCAsynNosqlTest::BuildObjectDataSaveToRedisRet(const NFGUID& self, NFMsg::PackNoSqlParam& nosqlParam, const std::string& strUseData)
{
    setCountRet++;
    if (nosqlParam.ret() != 0)
    {
        std::cout << "Nosql Bad!" << std::endl;
        return;
    }

    if (nosqlParam.opt_ret())
    {
        setCountRetSuc++;
    }
    else
    {
        setCountRetFail++;
    }

    if (setCountRet >= setCount)
    {
        endTime = NFGetTime();
        std::cout << "asyn save object use time:" << endTime - startTime
                  << " all:" << setCount << " suc:" << setCountRetSuc << " fail:" << setCountRetFail << std::endl;
        std::cout << "asyn save object handle finish" << std::endl;
    }
}
